#ifndef MINIOPENGLWIDGET_H
#define MINIOPENGLWIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>
#include <QMouseEvent>

#include "MiniHandler.h"
#include "MiniCamera.h"
#include "MiniBSplineCurveHandler.h"
#include "MiniCloudHandler.h"
#include "MiniBSplineSurfaceHandler.h"
#include "MiniDiscreteCurveHandler.h"
#include "MiniMeshHandler.h"
#include "MiniParaCurveHandler.h"
#include "MiniParaSurfaceHandler.h"

struct material_data
{
    float alpha;    // 镜面反射系数
    QMatrix3x3 R;   // 材质矩阵
};

struct lighting_data
{
    QVector3D color;    // 渲染颜色
    QVector3D pos;      // 点光源位置
    QVector3D decrease; // 衰减因子
};

class MiniOpenGLWidget : public QOpenGLWidget, QOpenGLFunctions_3_3_Core
{
    Q_OBJECT
public:
    enum { normal, catching };

    explicit MiniOpenGLWidget(QWidget *parent = nullptr);
    ~MiniOpenGLWidget();

    void setWireframe(bool wireframe);          // 设置渲染模式
    void setLighting(lighting_data data);       // 设置光照参数
    void setMaterial(material_data data);       // 设置材质参数
    void setControlPoints(bool limit);          // 设置是否限制显示控制点
    MiniHandler *registerObject(MiniObject*);   // 注册物体

protected:
    void drawObject(MiniHandler*);              // 绘制物体
    void checkObject(QPointF pos);              // 检查物体碰撞
    void modifyObject(QPointF pos);             // 修改物体

protected:
    virtual void initializeGL() override;
    virtual void paintGL() override;
    virtual void wheelEvent(QWheelEvent*) override;
    virtual void mousePressEvent(QMouseEvent *) override;
    virtual void mouseReleaseEvent(QMouseEvent *) override;
    virtual void mouseMoveEvent(QMouseEvent *) override;

protected:
    QOpenGLShaderProgram m_shader;  // 基本渲染器
    GLuint m_VAO;                   // 顶点数组对象标记
    GLuint m_VBO;                   // 顶点缓冲对象标记
    GLuint m_mode;                  // 绘图模式

    int m_status;                   // 系统状态
    bool m_limit;                   // 是否限制每个句柄可以显示的图元数量
    QPoint m_screen;                // 记录屏幕上点击的点
    MiniHandler *m_catching;        // 捕获对象
    MiniCamera m_camera;            // 相机对象
    material_data m_material;       // 材质信息
    lighting_data m_lighting;       // 光照信息

    QList<MiniHandler*> m_handlers; // 需要绘制的物体列表
};

#endif // MINIOPENGLWIDGET_H
